/*
  The panic.c file implements the panic function which halts the kernel on errors.
*/

#include <types.h>
#include <klib.h>
#include <i386_arch.h>
#include <pic.h>
#include <tty.h>
#include <panic.h>
#include <scheduler.h>

void panic(char *msg)
  {
    printf("\nKernel panic: %s",msg);
    irq_disable_all();
    halt();
  }

void memory_dump(char *address,int size)
  {
    int i,col;
    char vals[20];
    char *p,ch;
    

    for (i=0;i<size;i+=16)
      {
	printf("%08x:  ",address+i);
	for (col=0;(col<16) && ((i+col)<size);col++)
	  {
	    p=(address+i+col);
	    vals[col] = (*p>=32 && *p<127 ? *p : '.');
	    vals[col+1]='\0';
	    printf("%02x ",*p);
	    if (vals[col]=='\0')
	      vals[col]='.';	    
	  }

	
	// pad remaining values to fill-up a whole line
	for (;col<16;col++)
	  {
	    vals[col] = ' ';
	    vals[col+1]='\0';
	    printf("-- ");
	  }
	
	printf(" |%s|\n",vals);
      }
  }

void context_dump(uregs_t *regs)
  {
    printf("WE'RE IN THE CONTEXT OF: %s\n",current_process->name);

    printf("  EAX: %08x   EBX: %08x   ECX: %08x   EDX: %08x\n",regs->eax,regs->ebx,regs->ecx,regs->edx);
    printf("  ESI: %08x   EDI: %08x   ESP: %08x   EBP: %08x\n",regs->esi,regs->edi,regs->esp,regs->ebp);
    printf("  CS:  %08x   DS:  %08x   ES:  %08x\n",regs->cs,regs->ds,regs->es);
    printf("  USER ESP:   %08x        USER SS:    %08x\n",regs->user_esp,regs->user_ss);
    printf("  EIP: %08x   EFLAGS:     %08x\n",regs->eip,regs->eflags);

    return;
  }

void fake_context_dump(uregs_t *regs)
  {
  }


void warning_message(char *msg)
  {
    byte_t color;

    color=system_tty->color;
    system_tty->color=TTY_COLOR_ERROR;

    printf(msg);

    system_tty->color=color;
  }


void emergency_message(char *msg)
  {
    word_t *vmem;
    word_t wch;
    char c;
    int i;

    // point to video memory
    vmem=(word_t *)0xF0000000;
    
    for (i=0;msg[i]!='\0';i++)
      {
	c=msg[i];
	// 0x47 = red background, light gray text (default)
	wch = ((word_t)0x47<<8) | (byte_t)(c&0x0FF);
	*vmem++=wch;
      }

    irq_disable_all();
    halt();
  }
